home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / lib / rcscripts / sh / rc-daemon.sh next >
Text File  |  2006-04-25  |  7KB  |  397 lines

  1. # Copyright 1999-2004 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3. # $Header$
  4.  
  5. # RC functions to work with daemons (very alpha for now, and not finished)
  6.  
  7. RC_GOT_DAEMON="yes"
  8.  
  9. [ "${RC_GOT_FUNCTIONS}" != "yes" ] && source /sbin/functions.sh
  10.  
  11. # Stuff for getpids() and co
  12. declare -ax MASTER_PID=
  13. declare -ax PID_LIST=
  14. DAEMONS=
  15. PID_FILES=
  16. RC_RETRY_KILL="no"
  17. RC_RETRY_TIMEOUT=1
  18. RC_RETRY_COUNT=5
  19. RC_FAIL_ON_ZOMBIE="no"
  20.  
  21. # Override default settings with user settings ...
  22. #[ -f /etc/conf.d/rc ] && source /etc/conf.d/rc
  23.  
  24. getpidfile() {
  25.     local x=
  26.     local y=
  27.     local count=0
  28.     local count2=0
  29.     
  30.     if [ "$#" -ne 1 -o -z "${DAEMONS}" ]
  31.     then
  32.         return 1
  33.     else
  34.         for x in ${DAEMONS}
  35.         do
  36.             if [ "${x}" != "$1" ]
  37.             then
  38.                 count=$((count + 1))
  39.                 continue
  40.             fi
  41.             
  42.             if [ -n "${PID_FILES}" ]
  43.             then
  44.                 count2=0
  45.                 
  46.                 for y in ${PID_FILES}
  47.                 do
  48.                     if [ "${count}" -eq "${count2}" -a -f ${y} ]
  49.                     then
  50.                         echo "${y}"
  51.                         return 0
  52.                     fi
  53.                     
  54.                     count2=$((count2 + 1))
  55.                 done
  56.                 for y in ${PID_FILES}
  57.                 do
  58.                     if [ "$(eval echo \${y/${x}/})" != "${y}" -a -f ${y} ]
  59.                     then
  60.                         echo "${y}"
  61.                         return 0
  62.                     fi
  63.                 done
  64.             else
  65.                 if [ -f /var/run/${x}.pid ]
  66.                 then
  67.                     echo "/var/run/${x}.pid"
  68.                     return 0
  69.                 elif [ -f /var/run/${myservice}/${x}.pid ]
  70.                 then
  71.                     echo "/var/run/${myservice}/${x}.pid"
  72.                     return 0
  73.                 fi
  74.             fi
  75.             
  76.             count=$((count + 1))
  77.         done
  78.     fi
  79.     
  80.     return 1
  81. }
  82.  
  83. #
  84. # Simple funtion to return the pids of all the daemons in $DAEMONS
  85. # in the array $PID_LIST, with the master pids in $MASTER_PID.
  86. #
  87. getpids() {
  88.     local x=
  89.     local count=0
  90.     local pidfile=
  91.  
  92.     if [ -n "${DAEMONS}" ]
  93.     then
  94.         for x in ${DAEMONS}
  95.         do
  96.             MASTER_PID[${count}]=
  97.             PID_LIST[${count}]=
  98.  
  99.             pidfile="$(getpidfile ${x})"
  100.             if [ -n "${pidfile}" ]
  101.             then
  102.                 MASTER_PID[${count}]="$(< ${pidfile})"
  103.             fi
  104.             if [ -n "$(pidof ${x})" ]
  105.             then
  106.                 PID_LIST[${count}]="$(pidof ${x})"
  107.             fi
  108.             
  109.             count=$((count + 1))
  110.         done
  111.     fi
  112.  
  113.     return 0
  114. }
  115.  
  116. #
  117. # Return status:
  118. #   0 - Everything looks ok, or rc-script do not start any daemons
  119. #   1 - Master pid is dead, but other processes are running
  120. #   2 - Master pid and all others (if any), are dead
  121. #   3 - No pidfile, and no processes are running what so ever
  122. #
  123. checkpid() {
  124.     local x=
  125.     local count=0
  126.  
  127.     if [ "$#" -ne 1 -o -z "$1" -o -z "${DAEMONS}" -o \
  128.          "$(eval echo \${DAEMONS/$1/})" = "${DAEMONS}" ]
  129.     then
  130.         return 3
  131.     fi
  132.  
  133.     getpids
  134.  
  135.     for x in ${DAEMONS}
  136.     do
  137.         if [ "${x}" != "$1" ]
  138.         then
  139.             count=$((count + 1))
  140.             continue
  141.         fi
  142.  
  143.         if [ -z "${PID_LIST[${count}]}" -a -n "${MASTER_PID[${count}]}" ]
  144.         then
  145.             return 2
  146.         elif [ -z "${PID_LIST[${count}]}" -a -z "${MASTER_PID[${count}]}" ]
  147.         then
  148.             return 3
  149.         elif [ -n "${MASTER_PID[${count}]}" -a ! -d /proc/${MASTER_PID[${count}]} ]
  150.         then
  151.             return 1
  152.         fi
  153.         
  154.         count=$((count + 1))
  155.     done
  156.     
  157.     return 0
  158. }
  159.  
  160. start-single-daemon() {
  161.     local retval=0
  162.     local pidfile=
  163.     local pidretval=0
  164.     local daemon=
  165.     local SSD="start-stop-daemon"
  166.  
  167.     if [ "$(eval echo \${DAEMONS/$1/})" != "${DAEMONS}" ]
  168.     then
  169.         daemon="$1"
  170.         shift
  171.  
  172.         # Just a stupid sanity check, need to improve here.
  173.         # Basically we "check" that the daemon name is in
  174.         # the args to SSD.
  175.         if [ "$(eval echo \${*/${daemon}/})" = "$*" ]
  176.         then
  177.             return 1
  178.         fi
  179.     else
  180.         return 1
  181.     fi
  182.  
  183.     if [ -z "${DAEMONS}" -o "$#" -lt 1 -o -z "${daemon}" ]
  184.     then
  185.         return 1
  186.     else
  187.         ${SSD} $*
  188.         retval=$?
  189.  
  190.         if [ "${retval}" -ne 0 ]
  191.         then
  192.             return ${retval}
  193.         fi
  194.  
  195.         checkpid ${daemon}
  196.         pidretval=$?
  197.         # Need to rethink checkpid return values, as we prob
  198.         # need a switch or something that its ok, or not if
  199.         # the master pid is dead, but some instances are running.
  200.         if [ "${pidretval}" -ne 0 -a "${pidretval}" -ne 1 ]
  201.         then
  202.             return 1
  203.         fi
  204.     fi
  205.  
  206.     return ${retval}
  207. }
  208.  
  209. #
  210. # Stop a single daemon.  This is mainly used by stop-daemon().
  211. # It takes the following arguments:
  212. #
  213. #    --kill-pidfile    If the pidfile exists, remove it.
  214. #
  215. #    --fail-zombie     If the process was not running, exit with
  216. #                      a fail status.  Default is to exit cleanly.
  217. #
  218. stop-single-daemon() {
  219.     local retval=0
  220.     local pidfile=
  221.     local pidretval=0
  222.     local killpidfile="no"
  223.     local failonzombie="no"
  224.     local daemon=
  225.     local SSD="start-stop-daemon --stop --quiet"
  226.  
  227.     for x in $*
  228.     do
  229.         case ${x} in
  230.             --kill-pidfile)
  231.                 killpidfile="yes"
  232.                 ;;
  233.             --fail-zombie)
  234.                 failonzombie="yes"
  235.                 ;;
  236.             *)
  237.                 if [ "$(eval echo \${DAEMONS/${x}/})" != "${DAEMONS}" ]
  238.                 then
  239.                     if [ -n "${daemon}" ]
  240.                     then
  241.                         return 1
  242.                     fi
  243.                     
  244.                     daemon="${x}"
  245.                 fi
  246.                 ;;
  247.         esac
  248.     done
  249.  
  250.     if [ -z "${DAEMONS}" -o "$#" -lt 1 -o -z "${daemon}" ]
  251.     then
  252.         return 1
  253.     else
  254.         checkpid ${daemon}
  255.         pidretval=$?
  256.         if [ "${pidretval}" -eq 0 ]
  257.         then
  258.             pidfile="$(getpidfile ${daemon})"
  259.             if [ -n "${pidfile}" ]
  260.             then
  261.                 ${SSD} --pidfile ${pidfile}
  262.                 retval=$?
  263.             else
  264.                 ${SSD} --name ${daemon}
  265.                 retval=$?
  266.             fi
  267.         elif [ "${pidretval}" -eq 1 ]
  268.         then
  269.             ${SSD} --name ${daemon}
  270.             retval=$?
  271.         elif [ "${pidretval}" -eq 2 ]
  272.         then
  273.             if [ "${RC_FAIL_ON_ZOMBIE}" = "yes" -o "${failonzombie}" = "yes" ]
  274.             then
  275.                 retval=1
  276.             fi
  277.         elif [ "${pidretval}" -eq 3 ]
  278.         then
  279.             if [ "${RC_FAIL_ON_ZOMBIE}" = "yes" -o "${failonzombie}" = "yes" ]
  280.             then
  281.                 retval=1
  282.             fi
  283.         fi
  284.     fi
  285.  
  286.     #only delete the pidfile if the daemon is dead
  287.     if [ "${killpidfile}" = "yes" ]
  288.     then
  289.         checkpid ${daemon}
  290.         pidretval=$?
  291.         if [ "${pidretval}" -eq 2 -o "${pidretval}" -eq 3 ]
  292.         then
  293.             rm -f $(getpidfile ${x})
  294.         fi
  295.     fi
  296.  
  297.     #final sanity check
  298.     if [ "${retval}" -eq 0 ]
  299.     then
  300.         checkpid ${daemon}
  301.         pidretval=$?
  302.         if [ "${pidretval}" -eq 0 -o "${pidretval}" -eq 1 ]
  303.         then
  304.             retval=$((retval + 1))
  305.         fi
  306.     fi
  307.     
  308.     return ${retval}
  309. }
  310.  
  311. #
  312. # Should be used to stop daemons in rc-scripts.  It will
  313. # stop all the daemons in $DAEMONS.  The following arguments
  314. # are supported:
  315. #
  316. #    --kill-pidfile    Remove the pidfile if it exists (after
  317. #                      daemon is stopped)
  318. #
  319. #    --fail-zombie     If the process is not running, exit with
  320. #                      a fail status (default is to exit cleanly).
  321. #
  322. #    --retry           If not sucessfull, retry the number of times
  323. #                      as specified by $RC_RETRY_COUNT
  324. #
  325. stop-daemons() {
  326.     local x=
  327.     local count=0
  328.     local retval=0
  329.     local tmpretval=0
  330.     local pidretval=0
  331.     local retry="no"
  332.     local ssdargs=
  333.  
  334.     if [ -z "${DAEMONS}" ]
  335.     then
  336.         return 0
  337.     fi
  338.  
  339.     for x in $*
  340.     do
  341.         case ${x} in
  342.             --kill-pidfile)
  343.                 ssdargs="${ssdargs} --kill-pidfile"
  344.                 ;;
  345.             --fail-zombie)
  346.                 ssdargs="${ssdargs} --fail-zombie"
  347.                 ;;
  348.             --retry)
  349.                 retry="yes"
  350.                 ;;
  351.             *)
  352.                 eerror "  ERROR: invalid argument to stop-daemon()!"
  353.                 return 1
  354.                 ;;
  355.         esac
  356.     done
  357.  
  358.     if [ "${retry}" = "yes" -o "${RC_RETRY_KILL}" = "yes" ]
  359.     then
  360.         for x in ${DAEMONS}
  361.         do
  362.             count=0
  363.             pidretval=0
  364.         
  365.             while ([ "${pidretval}" -eq 0 -o "${pidretval}" -eq 1 ]) && \
  366.                   [ "${count}" -lt "${RC_RETRY_COUNT}" ]
  367.             do
  368.                 if [ "${count}" -ne 0 -a -n "${RC_RETRY_TIMEOUT}" ]
  369.                 then
  370.                     sleep ${RC_RETRY_TIMEOUT}
  371.                 fi
  372.  
  373.                 stop-single-daemon ${ssdargs} ${x}
  374.                 tmpretval=$?
  375.  
  376.                 checkpid ${x}
  377.                 pidretval=$?
  378.  
  379.                 count=$((count + 1))
  380.             done
  381.             
  382.             retval=$((retval + tmpretval))
  383.         done
  384.     else
  385.         for x in ${DAEMONS}
  386.         do
  387.             stop-single-daemon ${ssdargs} ${x}
  388.             retval=$((retval + $?))
  389.         done
  390.     fi
  391.  
  392.     return ${retval}
  393. }
  394.  
  395.  
  396. # vim:ts=4
  397.